// Copyright (C) 2013  Victor Fragoso <vfragoso@cs.ucsb.edu>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of the University of California, Santa Barbara nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL VICTOR FRAGOSO BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#ifndef OPTIMO_UTILS_MATRIX_UTILS_H_
#define OPTIMO_UTILS_MATRIX_UTILS_H_

#include <Eigen/Core>
#include <cmath>

namespace optimo {
namespace utils {
template <typename Scalar, int m, int n>
inline bool isFinite(const Eigen::Matrix<Scalar, m, n>& x) {
  bool flag = true;
  const Scalar* data = x.data();
  unsigned int i = 0;
  const unsigned int size = x.size();
  while (i < size && flag) {
    flag = std::isfinite(data[i++]);
  }
  return flag;
}

template <typename Scalar>
inline bool
isFinite(const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>& x) {
  bool flag = true;
  const Scalar* data = x.data();
  unsigned int i = 0;
  const unsigned int size = x.size();
  while (i < size && flag) {
    flag = std::isfinite(data[i++]);
  }
  return flag;
}

template <typename Scalar>
inline bool isFinite(const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>& x) {
  bool flag = true;
  const Scalar* data = x.data();
  unsigned int i = 0;
  const unsigned int size = x.size();
  while (i < size && flag) {
    flag = std::isfinite(data[i++]);
  }
  return flag;
}
}  // utils
}  // optimo
#endif
